package com.jichaoyun.service.util;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;

// 导入对应SMS模块的client
import com.tencentcloudapi.sms.v20210111.SmsClient;

// 导入要请求接口对应的request response类
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;


import com.jichaoyun.dao.mapper.SmsCacheMapper;
import com.jichaoyun.model.entity.SmsCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class SmsSendService {

    //正常充值短信模板
    //尊敬的客户（{1}）：您已成功充值{2}元，截至{3}，贵单位余额为{4}元。
    public static final String temp_recharge = "1502673";

    //余额报警
    //（{1}）尊敬的用户：您的蒸汽余额剩余{2}元，请您关注余额变化并及时交费充值，若已充值请忽略此短信。
    public static final String temp_balance = "1502661";

    //直流报警
    // {1}当前仪表供电为直流供电，请注意！
    public static final String temp_dcAlarm = "1502683";

    //通讯中断
    // 热用户{1}通讯已中断，请注意！
    public static final String temp_comAlarm = "1502686";

    //仪表组态修改报警
    //热网用户{1}仪表组态被修改，请注意！
    public static final String temp_paraAlarm = "2433387";

    //超限报警
    //(超限报警){1}当前{2}为{3}，进行{4}!
    public static final String temp_limitAlarm = "2433424";

    //门开报警
    //站点{1}柜门打开，请注意！
    public static final String temp_doorAlarm = "2433399";


    public static final String signName = "东港热电";

    //系统变量中获取
    public static final String SECRET_ID = System.getenv("TENCENT_SECRET_ID");
    public static final String SECRET_KEY = System.getenv("TENCENT_SECRET_KEY");


    public static final String sdkAppId = "1400989430";

    @Autowired
    public SmsCacheMapper smsCacheMapper;

    private static SmsSendService smsSendService;
    @PostConstruct
    private void init(){
        smsSendService = this;
        smsSendService.smsCacheMapper = this.smsCacheMapper;
    }


    // 创建一个DateTimeFormatter对象，用于格式化日期时间
//    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
    public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

//    /**
//     * 使用AK&SK初始化账号Client
//     * @param accessKeyId
//     * @param accessKeySecret
//     * @return Client
//     * @throws Exception
//     */
//    public static Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
//        Config config = new Config()
//                // 必填，您的 AccessKey ID
//                .setAccessKeyId(accessKeyId)
//                // 必填，您的 AccessKey Secret
//                .setAccessKeySecret(accessKeySecret);
//        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
//        config.endpoint = "dysmsapi.aliyuncs.com";
//        return new Client(config);
//    }




    /**
     * 腾讯云发送短信方法
     * @param phoneNumber 手机号
     * @param templateId 模版id
     * @param templateParams 参数
     * @return
     */
    public static Boolean sendSms(String phoneNumber,String templateId,String[] templateParams) {

        // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId，SecretKey。
        // 为了保护密钥安全，建议将密钥设置在环境变量中或者配置文件中，请参考凭证管理 https://github.com/TencentCloud/tencentcloud-sdk-java?tab=readme-ov-file#%E5%87%AD%E8%AF%81%E7%AE%A1%E7%90%86。
        // 硬编码密钥到代码中有可能随代码泄露而暴露，有安全隐患，并不推荐。
        // SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capi
        // Credential cred = new Credential("SecretId", "SecretKey");
        // Credential cred = new EnvironmentVariableCredentialsProvider().getCredentials();
        Credential cred = new Credential(SECRET_ID, SECRET_KEY);


        //实例化要请求产品(以sms为例)的client对象
        SmsClient client = new SmsClient(cred, "ap-guangzhou");

        /* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
         * 您可以直接查询SDK源码确定接口有哪些属性可以设置
         * 属性可能是基本类型，也可能引用了另一个数据结构
         * 推荐使用IDE进行开发，可以方便跳转查阅各个接口和数据结构的文档说明 */
        SendSmsRequest req = new SendSmsRequest();
        /* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
         * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号 */
        String[] phoneNumberSet = {"+86"+ phoneNumber};
        req.setPhoneNumberSet(phoneNumberSet);
        /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666 */
        // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
        req.setSmsSdkAppId(sdkAppId);
        /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名 */
        // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
        req.setSignName(signName);
        /* 模板 ID: 必须填写已审核通过的模板 ID */
        // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
        req.setTemplateId(templateId);
        /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
        req.setTemplateParamSet(templateParams);


        SendSmsResponse res = null;
        try {
            /* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
             * 返回的 res 是一个 SendSmsResponse 类的实例，与请求对象对应 */
            res = client.SendSms(req);
        } catch (TencentCloudSDKException e) {
            log.error("发送短信出错：", e);
            return Boolean.FALSE;
        }
        log.info("发送短信结果：{}",
                res != null ? SendSmsResponse.toJsonString(res) : "空响应");


        if (Objects.nonNull(res.getSendStatusSet()) && res.getSendStatusSet().length > 0 && "Ok".equals(res.getSendStatusSet()[0].getCode())){
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }



//todo @transactional
    public static void in_sms_recharge(String tels,String name, BigDecimal money, LocalDateTime time,BigDecimal balance,Integer stationNo){
        for(int i=0;i<tels.length();i+=11) {
            int end = Math.min(i + 11, tels.length());
            String tel = tels.substring(i, end);
            SmsCache smsCache = new SmsCache();
            smsCache.setTempName("短信正常充值");
            smsCache.setTel(tel.trim());
            smsCache.setStationName(name.trim());
            smsCache.setRechangeNum(money);
            smsCache.setTillTime(time);
            smsCache.setBalance(balance);
            smsCache.setTime(LocalDateTime.now());
            smsCache.setStationNo(stationNo);
            smsSendService.smsCacheMapper.insert(smsCache);
        }
    }
    /**
     * 充值短信接口
     * @param tel
     * @param name
     * @param money
     * @param time
     * @param balance
     * @throws Exception
     */
    public static String smsSend_recharge(String tel,String name, Float money, LocalDateTime time,Float balance) throws Exception {
        String formatTime = time.format(formatter);
        //正常充值短信模板
        //尊敬的客户（{1}）：您已成功充值{2}元，截至{3}，贵单位余额为{4}元。
        //构造模版参数
        List<String> paramsList = new ArrayList<>();
        paramsList.add(name);
        paramsList.add(String.valueOf(money));
        paramsList.add(formatTime);
        paramsList.add(String.valueOf(balance));
        String[] paramsArrayFromList = paramsList.toArray(new String[0]);
        Boolean isSend = sendSms(tel,temp_recharge,paramsArrayFromList);
        if(isSend){
            return "OK";
        }else{
            return "充值短信发送失败";

        }
    }


    public static void in_balance_sms(String tels,String name, BigDecimal balance,Integer stationNo){
        for(int i=0;i<tels.length();i+=11) {
            String tel = tels.substring(i, i + 11);
            SmsCache smsCache = new SmsCache();
            smsCache.setTempName("余额报警");
            smsCache.setTel(tel.trim());
            smsCache.setStationName(name.trim());
            smsCache.setBalance(balance);
            smsCache.setTime(LocalDateTime.now());
            smsCache.setStationNo(stationNo);
            smsSendService.smsCacheMapper.insert(smsCache);
        }
    }

    /**
     * 余额不足的提醒
     * @param tel
     * @param name
     * @param balance
     * @return
     * @throws Exception
     */
    public static String smsSend_balance(String tel,String name, Float balance) throws Exception {

        //余额报警
        //（{1}）尊敬的用户：您的蒸汽余额剩余{2}元，请您关注余额变化并及时交费充值，若已充值请忽略此短信。
        //构造模版参数
        List<String> paramsList = new ArrayList<>();
        paramsList.add(name);
        paramsList.add(String.valueOf(balance));
        String[] paramsArrayFromList = paramsList.toArray(new String[0]);
        Boolean isSend = sendSms(tel,temp_balance,paramsArrayFromList);
        if(isSend){
            return "OK";
        }else{
            //余额报警短信发送失败
            return "ERROR";

        }
    }

    public static void int_sms_dcAlarm(String tels, String name, Integer stationNo){
        for(int i=0;i<tels.length();i+=11) {
            String tel = tels.substring(i, i + 11);
            SmsCache smsCache = new SmsCache();
            smsCache.setTempName("直流供电提醒");
            smsCache.setTel(tel.trim());
            smsCache.setStationName(name);
            smsCache.setTime(LocalDateTime.now());
            smsCache.setStationNo(stationNo);
            smsSendService.smsCacheMapper.insert(smsCache);
        }

    }

    /**
     * 直流报警
     * @param tel
     * @param name
     * @return
     * @throws Exception
     */
    public static String smsSend_dcAlarm(String tel,String name) throws Exception {
        //直流报警
        // {1}当前仪表供电为直流供电，请注意！
        List<String> paramsList = new ArrayList<>();
        paramsList.add(name);
        String[] paramsArrayFromList = paramsList.toArray(new String[0]);
        Boolean isSend = sendSms(tel,temp_dcAlarm,paramsArrayFromList);
        if(isSend){
            return "OK";
        }else{
            //直流供电报警短信发送失败
            return "ERROR";

        }
    }

    public static void int_sms_comAlarm(String tels,String name,Integer stationNo){
        for(int i=0;i<tels.length();i+=11) {
            String tel = tels.substring(i, i + 11);
            SmsCache smsCache = new SmsCache();
            smsCache.setTempName("通讯中断提醒");
            smsCache.setTel(tel.trim());
            smsCache.setStationName(name);
            smsCache.setTime(LocalDateTime.now());
            smsCache.setStationNo(stationNo);
            smsSendService.smsCacheMapper.insert(smsCache);
        }
    }

    /**
     * 通讯中断报警
     * @param tel
     * @param name
     * @return
     * @throws Exception
     */
    public static String smsSend_comAlarm(String tel,String name) throws Exception {
        //通讯中断
        // 热用户{1}通讯已中断，请注意！
        List<String> paramsList = new ArrayList<>();
        paramsList.add(name);
        String[] paramsArrayFromList = paramsList.toArray(new String[0]);
        Boolean isSend = sendSms(tel,temp_comAlarm,paramsArrayFromList);
        if(isSend){
            return "OK";
        }else{
            //通讯中断警短信发送失败
            return "ERROR";

        }
    }


    public static void int_sms_paraAlarm(String tels,String name ,Integer stationNo){
        for(int i=0;i<tels.length();i+=11) {
            String tel = tels.substring(i, i + 11);
            SmsCache smsCache = new SmsCache();
            smsCache.setTempName("仪表组态报警");
            smsCache.setTel(tel);
            smsCache.setStationName(name);
            smsCache.setStationNo(stationNo);
            smsSendService.smsCacheMapper.insert(smsCache);
        }

    }


    /**
     * 仪表组态报警
     * @param tel
     * @param name
     * @return
     * @throws Exception
     */
    public static String smsSend_paraAlarm(String tel,String name) throws Exception {
        //仪表组态修改报警
        //热网用户{1}仪表组态被修改，请注意！
        List<String> paramsList = new ArrayList<>();
        paramsList.add(name);
        String[] paramsArrayFromList = paramsList.toArray(new String[0]);
        Boolean isSend = sendSms(tel,temp_paraAlarm,paramsArrayFromList);
        if(isSend){
            return "OK";
        }else{
            //仪表组态报警短信发送失败
            return "ERROR";
        }
    }




    public static void int_sms_doorAlarm(String tels,String name ,Integer stationNo){
        for(int i=0;i<tels.length();i+=11) {
            String tel = tels.substring(i, i + 11);
            SmsCache smsCache = new SmsCache();
            smsCache.setTempName("门开报警");
            smsCache.setTel(tel);
            smsCache.setStationName(name);
            smsCache.setStationNo(stationNo);
            smsSendService.smsCacheMapper.insert(smsCache);
        }
    }


    /**
     * 门开报警
     * @param tel
     * @param name
     * @return
     * @throws Exception
     */
    public static String smsSend_doorAlarm(String tel,String name) throws Exception {
        //门开报警
        //站点{1}柜门打开，请注意！
        List<String> paramsList = new ArrayList<>();
        paramsList.add(name);
        String[] paramsArrayFromList = paramsList.toArray(new String[0]);
        Boolean isSend = sendSms(tel,temp_doorAlarm,paramsArrayFromList);
        if(isSend){
            return "OK";
        }else{
            //门开报警
            return "ERROR";
        }
    }

    public static void in_sms_limitAlarm(String tels,String name,String para,String num, String message,Integer stationNo){
        for(int i=0;i<tels.length();i+=11) {
            String tel = tels.substring(i, i + 11);
            SmsCache smsCache = new SmsCache();
            smsCache.setTel(tel);
            smsCache.setTempName("超限报警");
            smsCache.setStationName(name);
            smsCache.setPara(para);
            smsCache.setNum(num);
            smsCache.setMessage(message);
            smsCache.setStationNo(stationNo);
            smsSendService.smsCacheMapper.insert(smsCache);
        }


    }

    /**
     * 超限报警
     * @param tel
     * @param name
     * @param para
     * @param num
     * @param message
     * @return
     * @throws Exception
     */
    public static String smsSend_limitAlarm(String tel,String name,String para,String num, String message) throws Exception {
        //超限报警
        //(超限报警){1}当前{2}为{3}，进行{4}!
        List<String> paramsList = new ArrayList<>();
        paramsList.add(name);
        paramsList.add(para);
        paramsList.add(num);
        paramsList.add(message);
        String[] paramsArrayFromList = paramsList.toArray(new String[0]);
        Boolean isSend = sendSms(tel,temp_limitAlarm,paramsArrayFromList);
        if(isSend){
            return "OK";
        }else{
            //超限报警短信发送失败
            return "ERROR";
        }
    }
}



